package com.allwees.bs.module.oms.context.processor;

import com.allwees.bs.core.model.coupon.constant.ECashLogType;
import com.allwees.bs.core.model.order.wf.order.EOrderAction;
import com.allwees.bs.core.model.order.wf.order.EOrderState;
import com.allwees.bs.core.model.order.wf.refund.ERefundState;
import com.allwees.bs.module.base.refund.AbstractRefundService;
import com.allwees.bs.module.oms.account.runner.AccountTransitUtils;
import com.allwees.bs.module.oms.dao.OmsOrderDao;
import com.allwees.bs.module.oms.dao.OmsOrderItemDao;
import com.allwees.bs.module.oms.dao.OrderDao;
import com.allwees.bs.module.oms.dao.OrderItemDao;
import com.allwees.bs.module.oms.dao.OrderRefundDao;
import com.allwees.bs.module.oms.entity.OmsOrder;
import com.allwees.bs.module.oms.entity.OmsOrderItem;
import com.allwees.bs.module.oms.entity.Order;
import com.allwees.bs.module.oms.entity.OrderItem;
import com.allwees.bs.module.oms.wf.EOmsOrderAction;
import com.allwees.bs.module.ums.dao.CustomerCashLogDao;
import com.allwees.bs.module.ums.dao.CustomerDao;
import com.allwees.bs.module.ums.entity.CustomerCashLog;
import com.allwees.bs.module.ums.service.CustomerCashService;
import com.allwees.core.common.constant.EStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;


@Service
@Slf4j
public class OrderRefundPostProcessor extends AbstractRefundService<OmsOrderItem> {

    @Autowired
    private OrderDao orderDao;
    @Autowired
    private OmsOrderDao omsOrderDao;
    @Autowired
    private OmsOrderItemDao omsOrderItemDao;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private OrderRefundDao orderRefundDao;
    @Autowired
    private CustomerCashService customerCashService;

    @Autowired
    private CustomerCashLogDao customerCashLogDao;

    @Autowired
    //private AccountService accountService;
    private AccountTransitUtils accountTransitUtils;

    @Autowired
    private CustomerDao customerDao;

    @Override
    protected void check(OmsOrderItem omsOrderItem, String userUuid) {
        boolean canApply = ((EStatus.OMS_WAIT_MERCHANT_SHIP.equals(omsOrderItem.getEStatus()) && !omsOrderItem.getCanShipping()) || EStatus.OMS_RECEIVED.equals(omsOrderItem.getEStatus()));
        Assert.isTrue(canApply, "订单项:[" + omsOrderItem.getUuid() + "]当前状态不可以退货");
    }

    @Override
    protected OmsOrderItem checkByUuid(String orderItemUuid) {
        OmsOrderItem omsOrderItem = omsOrderItemDao.findByUuid(orderItemUuid);
        Assert.notNull(omsOrderItem, "orderitem [uuid: " + orderItemUuid + "] is not exist");
        return omsOrderItem;
    }

    @Override
    protected boolean isWaitShip(OmsOrderItem omsOrderItem) {
        return EStatus.OMS_WAIT_MERCHANT_SHIP.getValue().equals(omsOrderItem.getStatus());
    }

    @Override
    public void doRefunded(OmsOrderItem omsOrderItem, Object req) {
        OrderItem orderItem = orderItemDao.findByUuid(omsOrderItem.getUuid());

        omsOrderItem.setRefundAt(orderItem.getRefundAt());
        omsOrderItem.setEStatus(EStatus.OMS_REFUND);
        omsOrderItemDao.updateByUuid(omsOrderItem, orderItem.getUuid());

        OmsOrder omsOrder = omsOrderDao.findByUuid(omsOrderItem.getOrderUuid());
        omsOrder.setRefundCount(omsOrder.getRefundCount() + 1);
        omsOrderDao.updateByUuid(omsOrder,omsOrderItem.getOrderUuid());
//        Customer user =  customerDao.findByUuid(orderItem.getUserUuid());
        //refundLogActionUtil.logAction(orderItem, EActionType.SKU_UNSHIPPED_REFUND,user.getIsInfluencer());
        accountTransitUtils.accountTransit(orderItem,"doRefundAmtWaitShip");
    }

    @Override
    protected void updateWithApply(OmsOrderItem omsOrderItem, Object req) {
        omsOrderItem.setEStatus(EStatus.OMS_REFUNDING);
        omsOrderItemDao.updateByUuid(omsOrderItem, omsOrderItem.getUuid());
    }

    @Override
    public boolean isAllRefunded(String orderUuid) {
        return omsOrderItemDao.findUnReviewItemCount(orderUuid) == 0;
    }

    @Override
    public void doOrderRefunded(String orderUuid,String orderItemUuid) {
        OmsOrder omsOrder = omsOrderDao.findByUuid(orderUuid);
        //OmsOrderItem omsOrderItem = omsOrderItemDao.findByUuid(orderItemUuid);
        Integer orderRefundedCount = orderRefundDao.getCountByOrderUuidAndState(orderUuid, ERefundState.COMPLETED);
        EOmsOrderAction action = null;
        EOrderAction orderAction = null;
        if (orderRefundedCount.equals(omsOrder.getQuantity())) {
            action = EOmsOrderAction.SYSTEM_CLOSE_BY_ALL_REFUND;
            orderAction = EOrderAction.SYSTEM_CLOSE_BY_ALL_REFUND;
        } else {
            orderAction = EOrderAction.USER_ALL_REVIEWED;
        }

        //更新订单状态
        if (action != null) {
            omsOrder.signal(action);
           /* if (null == omsOrder.getRefundCount()) {
                omsOrder.setRefundCount(0);
            }
            omsOrder.setRefundCount(omsOrder.getRefundCount() + 1);*/
            omsOrderDao.updateByUuid(omsOrder, omsOrder.getUuid());
        }

        Order order = orderDao.findByUuid(orderUuid);
        if (EOrderState.WAIT_SHIP.equals(order.getState()) || order.ended()) {
            return;
        }
        order.signal(orderAction);
        orderDao.updateByUuid(order, orderUuid);

        //customerCashService.refunded(order.getUserUuid(), order.getAmtCash());
        //saveLog(order.getUserUuid(), orderUuid, null, order.getAmtCash(), ECashLogType.REFUNDED);
    }

    @Override
    public void doOrderItemCashRefunded(String orderItemUuid) {
        OrderItem orderItem = orderItemDao.findByUuid(orderItemUuid);
        customerCashService.refunded(orderItem.getUserUuid(),  orderItem.getAmtCashSku());
        saveLog(orderItem.getUserUuid(), orderItem.getOrderUuid(), orderItem.getAmtCashSku());
    }

    /**
     * 保存资金变更日志
     *
     * @param userUuid
     * @param relateKey
     * @param value
     */
    private void saveLog(String userUuid, String relateKey,BigDecimal value) {
        CustomerCashLog userCashLog = new CustomerCashLog();
        userCashLog.setUserUuid(userUuid);
        userCashLog.setValue(value);
        userCashLog.setLogType(ECashLogType.REFUNDED);
        userCashLog.setRelateKey(relateKey);
        customerCashLogDao.create(userCashLog);
    }
}
